﻿using HCMS.CommonDtos;
using HCMS.Dtos.Base;
using HCMS.Entities.Base;
using HCMS.Entities.Manage;
using HCMS.Enum;
using HCMS.Extensions;
using HCMS.IRepositories.Base;
using HCMS.IRepositories.Manage;
using HCMS.IServices.Base;
using HCMS.Repositories.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;

namespace HCMS.Services.Base
{
    /// <summary>
    /// 公告 接收 对象 应用服务
    /// </summary>
    public class NoticeReceiveAppService : CommonAppService<BaseDbContext, NoticeReceive>, INoticeReceiveAppService
    {
        private readonly IRepository<NoticeReceive> baseNoticeReceiveRepository;
        private readonly INoticeReceiveRepository noticeReceiveRepository;
        private readonly INoticeRepository noticeRepository;
        private readonly IAdminRepository adminRepository;
        private readonly IAdminRoleRepository adminRoleRepository;

        public NoticeReceiveAppService(
            IRepository<NoticeReceive> baseNoticeReceiveRepository,
            INoticeReceiveRepository noticeReceiveRepository,
            INoticeRepository noticeRepository,
            IAdminRepository adminRepository,
            IAdminRoleRepository adminRoleRepository
            ) : base(baseNoticeReceiveRepository)
        {
            this.baseNoticeReceiveRepository = baseNoticeReceiveRepository;
            this.noticeReceiveRepository = noticeReceiveRepository;
            this.noticeRepository = noticeRepository;
            this.adminRepository = adminRepository;
            this.adminRoleRepository = adminRoleRepository;
        }

        /// <summary>
        /// 发布 公告
        /// </summary>
        /// <param name="noticeId">公告 Id</param>
        /// <param name="receiveType">接收类型</param>
        /// <param name="adminIds">指定 管理员 Ids</param>
        /// <param name="roleIds">指定 角色 Ids</param>
        /// <param name="updateUser">更新 人</param>
        /// <returns>接收公告的管理员 Ids</returns>
        public async Task<List<int>> ReleaseNotice(int noticeId, int[] receiveType, List<int> adminIds, List<int> roleIds, string updateUser)
        {
            var notice = await noticeRepository.FirstOrDefaultAsync(t => t.Id == noticeId);
            if (notice == null || notice.Status != 0)
            {
                return new List<int>();
            }

            #region 重置原来的接收人 接收状态
            var oldReceiveList = (await GetAllAsync())?.Where(t => t.NoticeId == noticeId)?.ToList();
            if (oldReceiveList != null && oldReceiveList.Any())
            {
                foreach (var item in oldReceiveList)
                {
                    if (item.Status != 0)
                    {
                        item.Status = 0;
                    }
                    else if (item.IsRead)
                    {
                        item.IsRead = false;
                        item.ReadTime = DateTime.MinValue;
                    }

                    item.UpdateTime = DateTime.Now;
                    item.UpdateUser = updateUser;

                    await BaseUpdateAsync(item);
                }
            }
            #endregion

            #region 获取接收人信息
            var userId = new List<int>();

            // 所有人
            if (receiveType.Contains((int)NoticeReceiveType.ALL))
            {
                var allAdmin = await adminRepository.AllList();
                allAdmin = allAdmin.Where(t => t.Status == 0)?.ToList();
                allAdmin = allAdmin ?? new List<Admin>();
                userId = allAdmin.Select(t => t.Id).ToList();
            }
            else
            {
                // 指定 人员
                if (receiveType.Contains((int)NoticeReceiveType.Admin))
                {
                    userId = adminIds;
                }
                // 指定 角色
                if (receiveType.Contains((int)NoticeReceiveType.Role))
                {
                    foreach (var roleId in roleIds)
                    {
                        var adminRole = await adminRoleRepository.FirstOrDefaultAsync(t => t.Status == 0 && t.RoleId == roleId);
                        if (adminRole == null) { continue; }

                        var admin = await adminRepository.FirstOrDefaultAsync(t => t.Status == 0 && t.Id == adminRole.AdminId);
                        if (admin == null) { continue; }

                        userId.Add(admin.Id);
                    }
                }
            }

            userId = userId ?? new List<int>();

            // 去重
            userId = userId.Distinct().ToList();

            // 之前接收过的人员，不再重复新增
            if (oldReceiveList != null && oldReceiveList.Any())
            {
                var oldReceiveUserId = oldReceiveList.Select(t => t.UserId).ToList();
                userId = userId.Where(t => !oldReceiveUserId.Contains(t))?.ToList();
            }
            #endregion

            #region 发布公告
            if (userId == null || !userId.Any())
            {
                // 存在之前接收过的人员，直接返回发布成功，不用重复发布
                if (oldReceiveList != null && oldReceiveList.Any())
                {
                    return oldReceiveList.Select(t => t.UserId).ToList();
                }

                return new List<int>();
            }

            // 写入本次的接收人信息
            foreach (var item in userId)
            {
                var receive = new NoticeReceive()
                {
                    NoticeId = noticeId,
                    UserId = item,
                    IsRead = false,
                    ReadTime = DateTime.MinValue,
                    Status = 0,

                    CreateTime = DateTime.Now,
                    CreateUser = updateUser,
                    UpdateTime = DateTime.Now,
                    UpdateUser = updateUser
                };

                await BaseInsertAsync(receive);
            }
            #endregion

            return userId;
        }

        /// <summary>
        /// 管理 列表
        /// </summary>
        /// <param name="searchArgs">搜索 参数</param>
        /// <param name="pager">分页 参数</param>
        /// <returns></returns>
        public async Task<ListPagerDto<object>> ManageList(SearchArgsDto searchArgs, PagerArgsDto pager)
        {
            if (!string.IsNullOrWhiteSpace(searchArgs.SearchName) && !string.IsNullOrWhiteSpace(searchArgs.SearchKey))
            {
                // 【管理员 姓名】转为【管理员 Id】搜索
                if (searchArgs.SearchName.IsSame("adminName"))
                {
                    searchArgs.SearchName = "userIds";
                    var adminIdList = (await adminRepository.GetListAsync()).Where(t => t.AdminName.Contains(searchArgs.SearchKey))?.Select(t => t.Id).ToList();
                    if (adminIdList != null && adminIdList.Any())
                    {
                        searchArgs.SearchKey = string.Join(",", adminIdList);
                    }
                    else
                    {
                        searchArgs.SearchKey = "";
                    }
                }
            }

            var noticeReceive = await noticeReceiveRepository.ManageList(searchArgs, pager);

            var result = new ListPagerDto<object>();
            result.PagerInfo = noticeReceive.PagerInfo;

            var data = new List<object>();
            foreach (var item in noticeReceive.Data)
            {
                // 关联 管理员 名称
                var adminName = string.Empty;
                var adminInfo = await adminRepository.FirstOrDefaultAsync(t => t.Id == item.UserId);
                if (adminInfo != null)
                {
                    adminName = adminInfo.AdminName;
                }

                data.Add(new
                {
                    id = item.Id,
                    createTime = item.CreateTime,
                    createUser = item.CreateUser,
                    updateTime = item.UpdateTime,
                    adminId = item.UserId,
                    adminName = adminName,
                    isRead = item.IsRead,
                    readTime = item.ReadTime
                });
            }

            result.Data = data;

            return result;
        }

        /// <summary>
        /// 根据接收人员 Id 获取公告列表
        /// </summary>
        /// <param name="userId">接收人员 Id</param>
        /// <param name="count">最大获取数量</param>
        /// <returns></returns>
        public async Task<List<NoticeListByUserDto>> NoticeListByUserId(int userId, int count)
        {
            count = (count <= 0 || count > 10) ? 10 : count;

            var receiveList = (await noticeReceiveRepository.ListByUserId(userId))?.Where(t => t.Status == 0)?.ToList();
            if (receiveList == null || receiveList.Count == 0)
            {
                return new List<NoticeListByUserDto>();
            }

            var noticeIdList = receiveList.Select(t => t.NoticeId).ToList();

            var noticeList = (await noticeRepository.ListByIds(noticeIdList))?.Where(t => t.Status == 0 && t.ExpiresTime >= DateTime.Now)?.ToList();
            if (noticeList == null || noticeList.Count == 0)
            {
                return new List<NoticeListByUserDto>();
            }

            // 最新、指定数量 数据
            noticeList = noticeList.OrderByDescending(t => t.Id).Take(count).ToList();

            var result = new List<NoticeListByUserDto>();
            foreach (var item in noticeList)
            {
                var noticeDto = new NoticeListByUserDto()
                {
                    Id = item.Id,
                    Title = item.Title,
                    Content = item.Content,
                };

                var receiveInfo = receiveList.FirstOrDefault(t => t.NoticeId == item.Id);
                if (receiveInfo != null)
                {
                    noticeDto.CreateTime = receiveInfo.UpdateTime;
                    noticeDto.IsRead = receiveInfo.IsRead;
                }

                result.Add(noticeDto);
            }

            // 按 发布时间[最新排前面]，重新调整 公告 列表 排序
            result = result.OrderByDescending(t => t.CreateTime).ToList();

            return result;
        }

    }
}
